package com.naihe.anderson.sms.manager;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.PendingIntent;
import android.content.Intent;
import android.content.SharedPreferences.Editor;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Handler;
import android.telephony.SmsManager;
import android.text.TextUtils;
import android.widget.Toast;

import com.naihe.anderson.sms.R;
import com.naihe.anderson.sms.activity.TalkMessageActivity;
import com.naihe.anderson.sms.application.NhSmsApp;
import com.naihe.anderson.sms.broadcastReceiver.DeliveryFilterSmsReceiver;
import com.naihe.anderson.sms.broadcastReceiver.SendFilterSmsReceiver;
import com.naihe.anderson.sms.constants.NhSmsConstants;
import com.naihe.anderson.sms.dao.NhSmsDao;
import com.naihe.anderson.sms.dao.SystemDao;
import com.naihe.anderson.sms.entity.ContactUser;
import com.naihe.anderson.sms.entity.Nhsms;
import com.naihe.anderson.sms.entity.NhsmsSession;
import com.naihe.anderson.sms.entity.SignatureMsg;
import com.naihe.anderson.sms.listener.OnCreateDataListener;
import com.naihe.anderson.sms.listener.OnNotifyDataNhSmsListener;
import com.naihe.anderson.sms.listener.OnNotifyDataSessionListener;
import com.naihe.anderson.sms.util.FileUtil;
import com.naihe.anderson.sms.util.ObjectUtil;

public class NhSmsMgr {

	SmsManager smsManager;
	
	NhSmsApp application;
	NhSmsDao nhSmsDao;
	SystemDao systemDao;
	
	ContactMgr contactMgr;
	NotificationMgr notificationMgr;
	
	Editor edit;
	
	List<NhsmsSession> nhsmsSessionLists;
	
	List<Nhsms> nhsmsForUpdateList;
	
	OnNotifyDataSessionListener dataSetChangForSessionListener;
	OnNotifyDataNhSmsListener dataSetChangForSmsListener;
	SystemSmsObserver systemSmsObserver;
	
	long currentNhsmsThreadId = -1;
	
	long nhsms_id = -1;
	long nhsms_session_id = -1;
	
	boolean ifFinishToGetData = false;
	
	//处理系统短信内容变更时的动作
	private class SystemSmsObserver extends ContentObserver {
		
		public SystemSmsObserver(Handler handler) {
			super(handler);
		}

		public void onChange(boolean selfChange) {
			FileUtil.addLog("NhSmsMgr::SystemSmsObserver onChange", NhSmsMgr.class, "NhSmsMgr", null);
			
		}
	}
	
	public NhSmsMgr(NhSmsApp app){
		this.application = app;
		smsManager = SmsManager.getDefault();
		nhSmsDao = new NhSmsDao(app);
		systemDao = new SystemDao(app);
		contactMgr = app.getContactMgr();
		notificationMgr = app.getNotificationMgr();
		edit = app.getDefaultSharedPreferences().edit();
		nhsmsSessionLists = new ArrayList<NhsmsSession>();
	}
	
	public void initData(){
		initSysSmsChangeListener();
		
		if(application.getDefaultSharedPreferences().getBoolean(NhSmsConstants.FIRST_CREATE_SMSDB, false)){
			initSmsFormNhDb();
		} else {
			firstCreateSmsDb();
		}
	}
	
	private void initSysSmsChangeListener() {
		systemSmsObserver = new SystemSmsObserver(new Handler());
	    application.getContentResolver().registerContentObserver(Uri.parse(Nhsms.SMS_URI_ALL), true, systemSmsObserver);		
	}
	
	public NhsmsSession getSessionById(long sessionId){
		for(NhsmsSession nhsmsSession : nhsmsSessionLists){
			if(nhsmsSession.getTid() == sessionId){
				return (NhsmsSession) ObjectUtil.copySerializableObj(nhsmsSession);
			}
		}
		return null;
	}
	
	/**
	 * 
	 */
	private void initSmsFormNhDb(){
		new InitSmsFormNhDbTask().execute();
	}

	public void refreshNhsmsData(){
		if(dataSetChangForSessionListener != null)
			dataSetChangForSessionListener.onDataChanged();
	}
	
	/**
	 * 应用安装时初始化手机短信
	 */
	private void firstCreateSmsDb(){
		new FirstCreateSmsDbTask().execute();
	}
	
	public void searchNhsmsByBody(String key){
		new SearchNhSmsDbTask(key).execute();
	}
	
	public void sendSmsBySignatureMsg(SignatureMsg sendMsg) {
		if(NhSmsApp.DEBUG_MODE) return;
		String smsBody = sendMsg.getBodyMsg();
        String smsAddress =   sendMsg.getContactNumbersForSave();
        String[] smsAddresseArray = smsAddress.split(";");
        
        List<Nhsms> nhsmsList = new ArrayList<Nhsms>();
        
        int size = smsAddresseArray.length;
        for (int i = 0; i < size; i++) {
        	String addressTemp  = smsAddresseArray[i];
        	
        	Date date = new Date();
        	Nhsms nhsms = new Nhsms();
			nhsms.setAddress(addressTemp);
			nhsms.setBody(smsBody);
			nhsms.setDate(date.getTime());
			nhsms.setDate_sent(date.getTime());
			nhsms.setError_code(0);
			nhsms.setLocked(0);
			nhsms.setProtocol(0);
			nhsms.setRead(1);
			nhsms.setReply_path_present(0);
			nhsms.setSeen(1);
			nhsms.setService_center("");
			nhsms.setStatus(Nhsms.STATUS_PENDING);
			nhsms.setSubject("");
			nhsms.setThread_id(-1);
			nhsms.setType(Nhsms.MESSAGE_TYPE_SENT);
			
			ContactUser contactUser = contactMgr.getContactUserById(contactMgr.getContactIdByPhoneNum(addressTemp));
			if(contactUser != null){
				nhsms.setPerson(contactUser.getContactId());
			} else {
				nhsms.setPerson(0);
			}
			
			nhsmsList.add(nhsms);
        }
        
        sendSms(nhsmsList, null);
        
        smsAddresseArray = null;
	}

	public void sendSms(List<Nhsms> nhsmsList, OnCreateDataListener listener){
		if(nhsmsList == null || nhsmsList.size() == 0)
			return;
		for(Nhsms nhsms : nhsmsList){
			long systemSmsID = systemDao.addSystemSms(nhsms);
			if(systemSmsID == -1)
				systemSmsID = getNhsms_id() + 1;
			FileUtil.addLog("NhSmsMgr::sendSms addSystemSms-systemSmsID" + systemSmsID, NhSmsMgr.class, "NhSmsMgr", null);
			
			nhsms.set_id(systemSmsID);
			setNhsms_id(systemSmsID);
			
			Intent sendIntent = new Intent(SendFilterSmsReceiver.ACTION_SMS_SEND); 
			sendIntent.putExtra(NhSmsConstants.NHSMS_INTENT_ID, systemSmsID);
			sendIntent.putExtra(NhSmsConstants.NHSMS_ADDRESS_INTENT, nhsms.getAddress());
	        PendingIntent sendPI = PendingIntent.getBroadcast(application, 0, sendIntent,PendingIntent.FLAG_UPDATE_CURRENT);
	        
	        Intent deliveryIntent = new Intent(DeliveryFilterSmsReceiver.ACTION_SMS_DELIVERY);  
	        deliveryIntent.putExtra(NhSmsConstants.NHSMS_INTENT_ID, systemSmsID);
	        deliveryIntent.putExtra(NhSmsConstants.NHSMS_ADDRESS_INTENT, nhsms.getAddress());
	        PendingIntent deliveryPI = PendingIntent.getBroadcast(application, 0, deliveryIntent, PendingIntent.FLAG_UPDATE_CURRENT); 
			
	        if(getBaseSendInfoMsg()){
	        	nhsms.setBody(nhsms.getBody() + "[" + getBaseShowSendBackMsg() + "]");
	        }
	        
			if(nhsms.getBody().length()>70){
            	List<String> contents = smsManager.divideMessage(nhsms.getBody());
            	for(String sms:contents){
            		smsManager.sendTextMessage(nhsms.getAddress(), null, sms, sendPI, deliveryPI);
            	}
            }else{
            	smsManager.sendTextMessage(nhsms.getAddress(), null, nhsms.getBody(), sendPI, deliveryPI);
            }
		}
		
		if(listener == null){
			insertNhsmsByList(nhsmsList);
		} else {
			new SendSmsDbTask(nhsmsList, listener).execute();
		}
	}
	/**
	 * 分页查询会话消息
	 * @param tid 会话ID
	 * @param limitPage 分页页数
	 */
	public void getNhsmsListByTidLimit(long tid, int limitPage){
		new LimitNhSmsDbTask(tid, limitPage).execute();
	}
	
	/**
	 * 
	 * @param type 消息类型
	 * @param errorCode 消息错误码
	 * @param status 消息状态
	 * @param smsId 消息ID
	 * @param address 电话号码
	 */
	public synchronized void updateNhSmsStatus(int type, int errorCode, int status, long smsId, String address, String action){
		
		List<Nhsms> nhsmsForUpdateList = new ArrayList<Nhsms>();
		FileUtil.addLog("NhSmsMgr::updateNhSmsStatus type=" + type + " || address=" + address, NhSmsMgr.class, "NhSmsMgr", null);
		for(NhsmsSession session : nhsmsSessionLists){
			if(session.getAddress().equals(address)){
				for(Nhsms nhsms : session.getNhsms()){
					if(nhsms.get_id() == smsId){
						nhsms.setType(type);
						nhsms.setError_code(errorCode);
						nhsms.setStatus(status);
						
						//消息回执报告
						if(getBaseShowSendBackMsg() && action.equals("SendFilterSmsReceiver")){
							ContactUser contactUser = contactMgr.getContactUserById(contactMgr.getContactIdByPhoneNum(address));
							String name = null;
							if(contactUser != null){
								name = contactUser.getName();
							} else {
								name = address;
							}
							
							if(status == Nhsms.STATUS_COMPLETE){
								Toast.makeText(application, application.getResources().getString(R.string.base_show_send_back_success, name), Toast.LENGTH_SHORT).show();
							} else {
								Toast.makeText(application, application.getResources().getString(R.string.base_show_send_back_error, name), Toast.LENGTH_SHORT).show();
							}
						}
						nhsmsForUpdateList.add(nhsms);
						break;
					}
				}
				
				if(dataSetChangForSmsListener != null && currentNhsmsThreadId == session.getTid()){
					NhsmsSession tempSession = (NhsmsSession) ObjectUtil.copySerializableObj(session);
					dataSetChangForSmsListener.onDataChanged(tempSession.getNhsms());
				}
				break;
			}
		}
		
		if(nhsmsForUpdateList.size() > 0){
			new UpdateNhSmsDbTask(nhsmsForUpdateList).execute();
			nhsmsForUpdateList.clear();
			nhsmsForUpdateList = null;
		}
		
	}
	
	public synchronized void setNhSessionPassword(long sessionId, String password){
		FileUtil.addLog("NhSmsMgr::setNhSessionPassword sessionId=" + sessionId + " || password=" + password, NhSmsMgr.class, "NhSmsMgr", null);
		for(NhsmsSession session : nhsmsSessionLists){
			if(session.getTid() == sessionId){
				session.setCipher(password);
				new SetNhSmsPasswordDbTask(sessionId, password).execute();
				break;
			}
		}
		
		if(dataSetChangForSessionListener != null)
			dataSetChangForSessionListener.onDataChanged();
	}
	
	public synchronized void updateNhSessionRead(long sessionId){
		for(NhsmsSession session : nhsmsSessionLists){
			if(session.getTid() == sessionId){
				if(session.getRead() == 1) break;
			
				for(Nhsms nhsms : session.getNhsms()){
					nhsms.setRead(1);
				}
				session.setRead(1);
				FileUtil.addLog("NhSmsMgr::updateNhSessionRead sessionId=" + sessionId, NhSmsMgr.class, "NhSmsMgr", null);
				new UpdateNhSmsReadDbTask((NhsmsSession)ObjectUtil.copySerializableObj(session)).execute();
				break;
			}
		}
		
		if(dataSetChangForSessionListener != null)
			dataSetChangForSessionListener.onDataChanged();
	}
	/**
	 * 保存消息
	 * @param nhsms
	 */
	List<Nhsms> nhsmsWaitList = new ArrayList<Nhsms>();
	public void insertNewNhsms(Nhsms nhsms){
		FileUtil.addLog("NhSmsMgr::insertNewNhsms ifFinishToGetData=" + ifFinishToGetData, NhSmsMgr.class, "NhSmsMgr", null);
		nhsmsWaitList.add(nhsms);
		if(ifFinishToGetData){//表示数据已经加载完成
			NhsmsSession tempSession =  insertNhsmsByList(nhsmsWaitList);
			
			if(nhsms.getType() == Nhsms.MESSAGE_TYPE_INBOX && tempSession != null){
				notificationMgr.showNotification(1, tempSession, currentNhsmsThreadId);
			}
		}
	}
	
	private void doNhsmsWaitList(){
		FileUtil.addLog("NhSmsMgr::doNhsmsWaitList nhsmsWaitList.size=" + nhsmsWaitList.size(), NhSmsMgr.class, "NhSmsMgr", null);
		if(nhsmsWaitList.size() > 0){
			NhsmsSession tempSession = insertNhsmsByList(nhsmsWaitList);
			notificationMgr.showNotification(nhsmsWaitList.size(), tempSession, currentNhsmsThreadId);
		}
	}
	
	/**
	 * 
	 * @param nhsmsSession
	 */
	public synchronized void deleteNhSession(NhsmsSession nhsmsSession){
		if(nhsmsSession != null){
			FileUtil.addLog("NhSmsMgr::deleteNhSession nhsmsSession" + nhsmsSession.getTid(), NhSmsMgr.class, "NhSmsMgr", null);
			nhsmsSessionLists.remove(nhsmsSession);
			
			if(dataSetChangForSessionListener != null)
				dataSetChangForSessionListener.onDataChanged();
			
			new DeleteSessionDbTask(nhsmsSession).execute();
			
			nhsmsSession = null;
		}
	}
	
	/**
	 * 
	 * @param delSessionList
	 */
	public synchronized void deleteNhSessionList(List<NhsmsSession> delSessions){
		if(delSessions != null && delSessions.size() > 0){
			FileUtil.addLog("NhSmsMgr::deleteNhSessionList nhsmsSessionSize" + delSessions.size(), NhSmsMgr.class, "NhSmsMgr", null);
			nhsmsSessionLists.removeAll(delSessions);
			
			if(dataSetChangForSessionListener != null)
				dataSetChangForSessionListener.onDataChanged();
			
			new DeleteSessionDbTask(delSessions).execute();
			
			delSessions.clear();
			delSessions = null;
		}
	}
	
	/**
	 * 
	 * @param delSessionList
	 */
	public void saveNhSessionList(List<Long> saveSessions,String filePath){
		if(saveSessions != null && saveSessions.size() > 0){
			FileUtil.addLog("NhSmsMgr::saveNhSessionList nhsmsSessionSize" + saveSessions.size(), NhSmsMgr.class, "NhSmsMgr", null);
			new SaveSessionDbTask(saveSessions, filePath).execute();
			saveSessions.clear();
			saveSessions = null;
		}
	}
	
	/**
	 * 
	 * @param nhsmsList
	 * @return NhsmsSession对象，用于直接展示会话
	 */
	private synchronized NhsmsSession insertNhsmsByList(List<Nhsms> nhsmsList){
		List<NhsmsSession> sessionsTempList = new ArrayList<NhsmsSession>();
		
		for(Nhsms nhsms : nhsmsList){
			boolean ifCreateSession = false;
			for(NhsmsSession session : nhsmsSessionLists){
				if(session.getAddress().equals(nhsms.getAddress())){
					session.setBody(nhsms.getBody());
					session.setDate(nhsms.getDate());
					//保证内存的中的某会话的短信为-PAGE_SIZE
					if(session.getNumsize() == NhsmsSession.PAGE_SIZE){
						FileUtil.addLog("NhSmsMgr::insertNhsmsByList > " + NhsmsSession.PAGE_SIZE + " || getNhsms.size=" + session.getNhsms().size(), NhSmsMgr.class, "NhSmsMgr", null);
						List<Nhsms> nhsms2 = session.getNhsms();
						nhsms2.remove(nhsms2.size() - 1);
						session.setNhsms(nhsms2);
						nhsms2.clear();
						nhsms2 = null;
					}
					session.setNumsize(session.getNumsize() + 1);
					
					if(session.getRead() == 1 && nhsms.getRead() == 1){
						session.setRead(1);
					} else {
						session.setRead(0);
					}
					ifCreateSession = true;
					
					nhsms.setThread_id(session.getTid());
					session.getNhsms().add(nhsms);
					FileUtil.addLog("NhSmsMgr::getSystemInfoId ids=> " + session.getTid() + "," + nhsms.get_id(), NhSmsMgr.class, "NhSmsMgr", null);
					sessionsTempList.add((NhsmsSession)ObjectUtil.copySerializableObj(session));
					break;
				}
			}
			
			if(!ifCreateSession){
				NhsmsSession session = new NhsmsSession();
				session.setBody(nhsms.getBody());
				session.setDate(nhsms.getDate());
				session.setNumsize(1);
				session.setRead(nhsms.getRead());
				session.setAddress(nhsms.getAddress());
				session.setPerson(nhsms.getPerson());
				try {Thread.sleep(3000);} catch (InterruptedException e) {}
				
				long[] ids = systemDao.getSystemInfoId(nhsms.getBody());
				FileUtil.addLog("NhSmsMgr::getSystemInfoId ids=> " + ids[0] + "," + ids[1], NhSmsMgr.class, "NhSmsMgr", null);
				if(ids[0] == -1 && ids[1] == -1){
					long tempTid = getNhsms_session_id() + 1;
					setNhsms_session_id(tempTid);
					
					ids[0] = tempTid;
				} else {
					nhsms.set_id(ids[1]);
					setNhsms_session_id(ids[0]);
				}
				
				session.setTid(ids[0]);
				nhsms.setThread_id(ids[0]);
				session.getNhsms().add(nhsms);
				
				nhsmsSessionLists.add(0, session);
				sessionsTempList.add(session);
			}
			
		}
		
		//更新界面
		Collections.sort(nhsmsSessionLists);
		if(dataSetChangForSessionListener != null)
			dataSetChangForSessionListener.onDataChanged();
		
		//插入数据库
		new InsertSmsDbTask(nhsmsList, sessionsTempList).execute();
		
		if(sessionsTempList.size() == 1){
			NhsmsSession nhsmsSession = sessionsTempList.get(0);
			if(dataSetChangForSmsListener != null && currentNhsmsThreadId == nhsmsSession.getTid()){
				dataSetChangForSmsListener.onDataChanged(nhsmsSession.getNhsms());
				if(nhsmsSession.getRead() == 0){
					updateNhSessionRead(nhsmsSession.getTid());
				}
			}
			return nhsmsSession;
		} else {
			return null;
		}
	}
	
	
	//=============================================Class=================================================================
	
	class FirstCreateSmsDbTask extends AsyncTask<String, Object, Boolean>{
		List<Nhsms> nhsmsLists = null;
		List<NhsmsSession> nhsmsSessionListsTemp = null;
		
		int nhsms_temp_id = -1;
		int nhsms_temp_session_id = -1;
		
		public FirstCreateSmsDbTask(){
			nhsmsLists = new ArrayList<Nhsms>();
			nhsmsSessionListsTemp = new ArrayList<NhsmsSession>();
		}
		
		@Override
		protected void onPreExecute() {
		}
		
		@Override
		protected Boolean doInBackground(String... params) {
			Map<Long, NhsmsSession> tempMap = new HashMap<Long, NhsmsSession>();
			//读取系统的消息
			nhsmsLists.addAll(systemDao.getSystemSms());
			
			for(Nhsms nhsms : nhsmsLists){
				NhsmsSession session = tempMap.get(nhsms.getThread_id());
				Long contactId = contactMgr.getContactIdByPhoneNum(nhsms.getAddress());
				if(contactId != null){
					nhsms.setPerson(contactId.longValue());
				} else {
					nhsms.setPerson(0);
				}
				
				if(session == null){
					session = new NhsmsSession();
					session.setAddress(nhsms.getAddress());
					session.setBody(nhsms.getBody());
					session.setDate(nhsms.getDate());
					session.setProtocol(nhsms.getProtocol());
					session.setRead(nhsms.getRead());
					session.setTid(nhsms.getThread_id());
					session.setPerson(nhsms.getPerson());
					session.setNumsize(1);
				} else {
					if(session.getDate() < nhsms.getDate()){
						session.setBody(nhsms.getBody());
						session.setDate(nhsms.getDate());
					}
					session.setNumsize(session.getNumsize() + 1);
				}
				
				if(!TextUtils.isEmpty(nhsms.getAddress())){
					session.setAddress(nhsms.getAddress());
				}
				
				if(session.getNhsms().size() <= 50){
					session.getNhsms().add(nhsms);
				}
				
				tempMap.put(session.getTid(), session);
			}
			
			for(Map.Entry<Long, NhsmsSession> entry : tempMap.entrySet()){
				Collections.sort(entry.getValue().getNhsms());
				nhsmsSessionListsTemp.add(entry.getValue());
			}
			
			nhSmsDao.insertOrUpdateNhSmsSessionEntity(nhsmsSessionListsTemp);
			nhSmsDao.insertOrUpdateNhSmsEntity(nhsmsLists);
			
			nhsms_temp_id = nhSmsDao.findNhsmsMaxId();
			nhsms_temp_session_id = nhSmsDao.findSessionMaxTid();
			
			if(tempMap != null){
				tempMap.clear();
				tempMap = null;
			}
			
			if(nhsmsLists != null){
				nhsmsLists.clear();
				nhsmsLists = null;
			}
			
			return true;
		}

		@Override
		protected void onProgressUpdate(Object... values) {
			
		}
		
		@Override
		protected void onPostExecute(Boolean result) {
			FileUtil.addLog("NhSmsMgr::FirstCreateSmsDbTask finish", NhSmsMgr.class, "NhSmsMgr", null);
			ifFinishToGetData = true;
			if(result != null && result){
				edit.putBoolean(NhSmsConstants.FIRST_CREATE_SMSDB, true);
				edit.putLong(NhSmsConstants.NHSMS_MAX_ID, nhsms_temp_id);
				edit.putLong(NhSmsConstants.NHSMS_SESSION_MAX_ID, nhsms_temp_session_id);
				nhsms_session_id = nhsms_temp_session_id;
				nhsms_id = nhsms_temp_id;
				edit.commit();
				
				nhsmsSessionLists.addAll(nhsmsSessionListsTemp);
				Collections.sort(nhsmsSessionLists);
				if(dataSetChangForSessionListener != null)
					dataSetChangForSessionListener.onDataChanged();
				doNhsmsWaitList();
			}
			if(nhsmsSessionListsTemp != null){
				nhsmsSessionListsTemp.clear();
				nhsmsSessionListsTemp = null;
			}
		}
	}
	
	class InsertSmsDbTask extends AsyncTask<String, Object, Boolean>{
		List<Nhsms> nhsmsLists = null;
		List<NhsmsSession> nhsmsSessionListsTemp = null;
		
		public InsertSmsDbTask(List<Nhsms> nhsmsLists, List<NhsmsSession> nhsmsSessionListsTemp){
			this.nhsmsLists = nhsmsLists;
			this.nhsmsSessionListsTemp = nhsmsSessionListsTemp;
		}
		
		@Override
		protected void onPreExecute() {
		}
		
		@Override
		protected Boolean doInBackground(String... params) {
			nhSmsDao.insertOrUpdateNhSmsSessionEntity(nhsmsSessionListsTemp);
			nhSmsDao.insertOrUpdateNhSmsEntity(nhsmsLists);
			return true;
		}

		@Override
		protected void onPostExecute(Boolean result) {
			if(nhsmsSessionListsTemp != null){
				nhsmsSessionListsTemp.clear();
				nhsmsSessionListsTemp = null;
			}
			if(nhsmsLists != null){
				nhsmsLists.clear();
				nhsmsLists = null;
			}
		}
	}
	
	class SendSmsDbTask extends AsyncTask<String, Object, Boolean>{
		List<Nhsms> nhsmsLists = null;
		OnCreateDataListener listener;
		
		List<Nhsms> createNhsmsList = new ArrayList<Nhsms>();
		List<NhsmsSession> createSessionsList = new ArrayList<NhsmsSession>();
		
		public SendSmsDbTask(List<Nhsms> nhsmsLists, OnCreateDataListener listener){
			this.nhsmsLists = nhsmsLists;
			this.listener = listener;
		}
		
		@Override
		protected void onPreExecute() {
			boolean ifCreateSession = false;
			
			List<NhsmsSession> sessionsTempList = new ArrayList<NhsmsSession>();
			List<Nhsms> insertNhsmsList = new ArrayList<Nhsms>();
			
			for(Nhsms nhsms : nhsmsLists){
				for(NhsmsSession session : nhsmsSessionLists){
					if(session.getAddress().equals(nhsms.getAddress())){
						session.setBody(nhsms.getBody());
						session.setDate(nhsms.getDate());
						//保证内存的中的某会话的短信为-PAGE_SIZE
						if(session.getNumsize() == NhsmsSession.PAGE_SIZE){
							FileUtil.addLog("NhSmsMgr::SendSmsDbTask::insertNhsmsByList > " + NhsmsSession.PAGE_SIZE + " || getNhsms.size=" + session.getNhsms().size(), NhSmsMgr.class, "NhSmsMgr", null);
							session.getNhsms().remove(NhsmsSession.PAGE_SIZE - 1);
						}
						session.setNumsize(session.getNumsize() + 1);
						
						if(session.getRead() == 1 && nhsms.getRead() == 1){
							session.setRead(1);
						} else {
							session.setRead(0);
						}
						ifCreateSession = true;
						
						nhsms.setThread_id(session.getTid());
						session.getNhsms().add(nhsms);
						FileUtil.addLog("NhSmsMgr::SendSmsDbTask::getSystemInfoId ids=> " + session.getTid() + "," + nhsms.get_id(), NhSmsMgr.class, "NhSmsMgr", null);
						
						sessionsTempList.add(session);
						insertNhsmsList.add(nhsms);
						break;
					}
				}
				
				if(!ifCreateSession){
					createNhsmsList.add(nhsms);
				}
				
			}
			
			if(sessionsTempList.size() > 0){
				//更新界面
				Collections.sort(nhsmsSessionLists);
				if(dataSetChangForSessionListener != null)
					dataSetChangForSessionListener.onDataChanged();
				
				//插入数据库
				new InsertSmsDbTask(insertNhsmsList, sessionsTempList).execute();
			} else {
				insertNhsmsList.clear();
				insertNhsmsList = null;
				sessionsTempList.clear();
				sessionsTempList = null;
			}
		}
		
		@Override
		protected Boolean doInBackground(String... params) {
			for(Nhsms nhsms : createNhsmsList){
				NhsmsSession session = new NhsmsSession();
				session.setBody(nhsms.getBody());
				session.setDate(nhsms.getDate());
				session.setNumsize(1);
				session.setRead(nhsms.getRead());
				session.setAddress(nhsms.getAddress());
				session.setPerson(nhsms.getPerson());
				try {Thread.sleep(3000);} catch (InterruptedException e) {}
				
				long[] ids = systemDao.getSystemInfoId(nhsms.getBody());
				FileUtil.addLog("NhSmsMgr::SendSmsDbTask::getSystemInfoId ids=> " + ids[0] + "," + ids[1], NhSmsMgr.class, "NhSmsMgr", null);
				if(ids[0] == -1 && ids[1] == -1){
					long tempTid = getNhsms_session_id() + 1;
					setNhsms_session_id(tempTid);
					
					ids[0] = tempTid;
				} else {
					nhsms.set_id(ids[1]);
					setNhsms_session_id(ids[0]);
				}
				
				session.setTid(ids[0]);
				nhsms.setThread_id(ids[0]);
				session.getNhsms().add(nhsms);
				
				createSessionsList.add(session);
			}
			return null;
		}

		@Override
		protected void onPostExecute(Boolean result) {
			if(createSessionsList.size() > 0){
				nhsmsSessionLists.addAll(0, createSessionsList);
				
				//更新界面
				Collections.sort(nhsmsSessionLists);
				if(dataSetChangForSessionListener != null)
					dataSetChangForSessionListener.onDataChanged();
				
				//插入数据库
				new InsertSmsDbTask(createNhsmsList, createSessionsList).execute();
				
				if(createSessionsList.size() == 1){
					Intent intent = new Intent(application, TalkMessageActivity.class);
					intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
					intent.putExtra("NhsmsSession", createSessionsList.get(0));
					application.startActivity(intent);
				}
			}
			
			if(listener != null) listener.OnCreateData();
		}
	}
	
	class InitSmsFormNhDbTask extends AsyncTask<String, Object, Boolean>{
		
		List<NhsmsSession> nhsmsSessionListsTemp = null;
		
		public InitSmsFormNhDbTask(){
			nhsmsSessionListsTemp = new ArrayList<NhsmsSession>();
		}
		
		@Override
		protected void onPreExecute() {
		}
		
		@Override
		protected Boolean doInBackground(String... params) {
			nhsmsSessionListsTemp.addAll(nhSmsDao.queryAllNhsmsSessionList());
			return true;
		}

		@Override
		protected void onPostExecute(Boolean result) {
			FileUtil.addLog("NhSmsMgr::InitSmsFormNhDbTask finish", NhSmsMgr.class, "NhSmsMgr", null);
			ifFinishToGetData = true;
			if(result != null && result){
				nhsmsSessionLists.addAll(nhsmsSessionListsTemp);
				Collections.sort(nhsmsSessionLists);
				if(dataSetChangForSessionListener != null)
					dataSetChangForSessionListener.onDataChanged();
				
				doNhsmsWaitList();
			}
			if(nhsmsSessionListsTemp != null){
				nhsmsSessionListsTemp.clear();
				nhsmsSessionListsTemp = null;
			}
		}
	}
	
	class SearchNhSmsDbTask extends AsyncTask<String, Object, Boolean>{
		
		List<Nhsms> nhsmsListTemp = null;
		String serchKey = "";
		
		public SearchNhSmsDbTask(String serchKey){
			nhsmsListTemp = new ArrayList<Nhsms>();
			this.serchKey = serchKey;
		}
		
		@Override
		protected void onPreExecute() {
		}
		
		@Override
		protected Boolean doInBackground(String... params) {
			nhsmsListTemp.addAll(nhSmsDao.searchNhsmsList(serchKey));
			return true;
		}

		@Override
		protected void onPostExecute(Boolean result) {
			FileUtil.addLog("NhSmsMgr::SearchNhSmsDbTask finish serchKey=" + serchKey, NhSmsMgr.class, "NhSmsMgr", null);
			if(dataSetChangForSmsListener != null)
				dataSetChangForSmsListener.onDataChanged(nhsmsListTemp);
		}
	}

	class LimitNhSmsDbTask extends AsyncTask<String, Object, Boolean>{
		
		List<Nhsms> nhsmsListTemp = null;
		long threadId = 0;
		int limitPageNumber = 0;
		
		public LimitNhSmsDbTask(long tid, int limitPage){
			nhsmsListTemp = new ArrayList<Nhsms>();
			threadId = tid;
			limitPageNumber = limitPage;
		}
		
		@Override
		protected void onPreExecute() {
		}
		
		@Override
		protected Boolean doInBackground(String... params) {
			nhsmsListTemp.addAll(nhSmsDao.queryAllNhsmsList(threadId + "", limitPageNumber));
			return true;
		}

		@Override
		protected void onPostExecute(Boolean result) {
			if(dataSetChangForSmsListener != null)
				dataSetChangForSmsListener.onDataChanged(nhsmsListTemp);
			FileUtil.addLog("NhSmsMgr::sendSms finish threadId=" + threadId + " || limitPageNumber=" + limitPageNumber, NhSmsMgr.class, "NhSmsMgr", null);
		}
	}
	
	class UpdateNhSmsDbTask extends AsyncTask<String, Object, Boolean>{
		
		List<Nhsms> nhsmsListTemp = null;
		
		public UpdateNhSmsDbTask(List<Nhsms> updateList){
			nhsmsListTemp = new ArrayList<Nhsms>();
			nhsmsListTemp.addAll(updateList);
		}
		
		@Override
		protected Boolean doInBackground(String... params) {
			nhSmsDao.insertOrUpdateNhSmsEntity(nhsmsListTemp);
			//插入系统的数据库
			for(Nhsms nhsms : nhsmsListTemp){
				systemDao.updateSystemSms(nhsms);
			}
			return true;
		}
		
		@Override
		protected void onPostExecute(Boolean result) {
			if(nhsmsListTemp != null){
				nhsmsListTemp.clear();
				nhsmsListTemp = null;
			}
		}
	}
	
	class UpdateNhSmsReadDbTask extends AsyncTask<String, Object, Boolean>{
		NhsmsSession nhsmsSession = null;
		
		public UpdateNhSmsReadDbTask(NhsmsSession nhsmsSession){
			this.nhsmsSession = nhsmsSession;
		}
		
		@Override
		protected Boolean doInBackground(String... params) {
			if(nhsmsSession != null){
				nhSmsDao.updateReadType(nhsmsSession);
				systemDao.updateSystemReadSms(nhsmsSession);
			}
			return true;
		}
	}
	
	class SetNhSmsPasswordDbTask extends AsyncTask<String, Object, Boolean>{
		long sessionId = -1;
		String password = "";
		
		public SetNhSmsPasswordDbTask(long sessionId,String passwd){
			this.sessionId = sessionId;
			this.password = passwd;
		}
		
		@Override
		protected Boolean doInBackground(String... params) {
			if(sessionId > -1){
				nhSmsDao.setSessionPasswd(sessionId, password);
			}
			return true;
		}
	}
	
	class DeleteSessionDbTask extends AsyncTask<String, Object, Boolean>{
		List<NhsmsSession> nhsmsSessionsList = new ArrayList<NhsmsSession>();
		
		public DeleteSessionDbTask(NhsmsSession nhsmsSession){
			this.nhsmsSessionsList.add(nhsmsSession);
		}
		
		public DeleteSessionDbTask(List<NhsmsSession> delSessions){
			this.nhsmsSessionsList.addAll(delSessions);
		}
		
		@Override
		protected Boolean doInBackground(String... params) {
			if(nhsmsSessionsList.size() > 0){
				nhSmsDao.deleteNhSmsSessionEntity(nhsmsSessionsList);
				for(NhsmsSession session : nhsmsSessionsList){
					systemDao.deleteSystemSmsByTid(session.getTid());
				}
			}
			return true;
		}
		
		@Override
		protected void onPostExecute(Boolean result) {
			nhsmsSessionsList.clear();
			nhsmsSessionsList = null;
		}
	}
	
	class SaveSessionDbTask extends AsyncTask<String, Object, Boolean>{
		List<Long> nhsmsSessionsList = new ArrayList<Long>();
		String filePath = "";
		
		public SaveSessionDbTask(Long nhsmsSession, String filePath){
			this.nhsmsSessionsList.add(nhsmsSession);
			this.filePath = filePath;
		}
		
		public SaveSessionDbTask(List<Long> saveSessions, String filePath){
			this.nhsmsSessionsList.addAll(saveSessions);
			this.filePath = filePath;
		}
		
		@Override
		protected Boolean doInBackground(String... params) {
			if(nhsmsSessionsList.size() > 0){
				FileOutputStream fos = null;
				try{
					String save = nhSmsDao.queryForSave(nhsmsSessionsList);
					File file = new File(filePath);
					fos = new FileOutputStream(file, false);
					fos.write(save.getBytes());
					fos.flush();
					file = null;
				}catch (Exception e) {
					
				}finally{
					try {
						if (fos != null){ fos.close(); fos = null;}
					} catch (IOException e) {}
				}
			}
			return true;
		}
		
		@Override
		protected void onPostExecute(Boolean result) {
			Toast.makeText(application, application.getResources().getString(R.string.menu_popup_save_body, filePath), Toast.LENGTH_LONG).show();
			nhsmsSessionsList.clear();
			nhsmsSessionsList = null;
			filePath = null;
		}
	}
	//=============================================UI=============================================================
	public List<NhsmsSession> getNsSmsSessionList(){
		if(nhsmsSessionLists == null)
			nhsmsSessionLists = new ArrayList<NhsmsSession>();
		return nhsmsSessionLists;
	}

	public void setDataSetChangForSessionListener(OnNotifyDataSessionListener dataSetChangListener) {
		this.dataSetChangForSessionListener = dataSetChangListener;
	}

	public void setDataSetChangForSmsListener(OnNotifyDataNhSmsListener dataSetChangForSmsListener, long currentTId) {
		this.dataSetChangForSmsListener = dataSetChangForSmsListener;
		this.currentNhsmsThreadId = currentTId;
	}

	public long getNhsms_id() {
		if(nhsms_id == -1){
			nhsms_id = application.getDefaultSharedPreferences().getLong(NhSmsConstants.NHSMS_MAX_ID, 0);
		}
		return nhsms_id;
	}

	public long getNhsms_session_id() {
		if(nhsms_session_id == -1){
			nhsms_session_id = application.getDefaultSharedPreferences().getLong(NhSmsConstants.NHSMS_SESSION_MAX_ID, 0);
		}
		return nhsms_session_id;
	}

	public void setNhsms_id(long nhsms_id) {
		edit.putLong(NhSmsConstants.NHSMS_MAX_ID, nhsms_id);
		edit.commit();
		this.nhsms_id = nhsms_id;
	}

	public void setNhsms_session_id(long nhsms_session_id) {
		edit.putLong(NhSmsConstants.NHSMS_SESSION_MAX_ID, nhsms_session_id);
		edit.commit();
		this.nhsms_session_id = nhsms_session_id;
	}

	public boolean isIfFinishToGetData() {
		return ifFinishToGetData;
	}
	
	Boolean baseShowNotif;
	public boolean getBaseShowNotif(){
		if(baseShowNotif == null)
			baseShowNotif = application.getDefaultSharedPreferences().getBoolean("baseShowNotif", true);
		return baseShowNotif;
	}
	
	public void setBaseShowNotif(boolean baseShowNotif){
		edit.putBoolean("baseShowNotif", baseShowNotif);
		edit.commit();
		this.baseShowNotif = baseShowNotif;
	}
	
//	Boolean baseGetMsgRing;
//	public boolean getBaseGetMsgRing(){
//		if(baseGetMsgRing == null)
//			baseGetMsgRing = application.getDefaultSharedPreferences().getBoolean("baseGetMsgRing", true);
//		return baseGetMsgRing;
//	}
//	
//	public void setBaseGetMsgRing(boolean baseGetMsgRing){
//		edit.putBoolean("baseGetMsgRing", baseGetMsgRing);
//		edit.commit();
//		this.baseGetMsgRing = baseGetMsgRing;
//	}
	
	Boolean baseGetMsgVibrator;
	public boolean getBaseGetMsgVibrator(){
		if(baseGetMsgVibrator == null)
			baseGetMsgVibrator = application.getDefaultSharedPreferences().getBoolean("baseGetMsgVibrator", false);
		return baseGetMsgVibrator;
	}
	
	public void setBaseGetMsgVibrator(boolean baseGetMsgVibrator){
		edit.putBoolean("baseGetMsgVibrator", baseGetMsgVibrator);
		edit.commit();
		this.baseGetMsgVibrator = baseGetMsgVibrator;
	}
	
	Boolean baseShowNewSmsBody;
	public boolean getBaseShowNewSmsBody(){
		if(baseShowNewSmsBody == null)
			baseShowNewSmsBody = application.getDefaultSharedPreferences().getBoolean("baseShowNewSmsBody", true);
		return baseShowNewSmsBody;
	}

	public void setBaseShowNewSmsBody(boolean baseShowNewSmsBody){
		edit.putBoolean("baseShowNewSmsBody", baseShowNewSmsBody);
		edit.commit();
		this.baseShowNewSmsBody = baseShowNewSmsBody;
	}
	
	Boolean baseShowNewSmsName;
	public boolean getBaseShowNewSmsName(){
		if(baseShowNewSmsName == null)
			baseShowNewSmsName = application.getDefaultSharedPreferences().getBoolean("baseShowNewSmsName", true);
		return baseShowNewSmsName;
	}

	public void setBaseShowNewSmsName(boolean baseShowNewSmsName){
		edit.putBoolean("baseShowNewSmsName", baseShowNewSmsName);
		edit.commit();
		this.baseShowNewSmsName = baseShowNewSmsName;
	}
	
	Boolean baseShowNewSmsHeadImage;
	public boolean getBaseShowNewSmsHeadImage(){
		if(baseShowNewSmsHeadImage == null)
			baseShowNewSmsHeadImage = application.getDefaultSharedPreferences().getBoolean("baseShowNewSmsHeadImage", true);
		return baseShowNewSmsHeadImage;
	}

	public void setBaseShowNewSmsHeadImage(boolean baseShowNewSmsHeadImage){
		edit.putBoolean("baseShowNewSmsHeadImage", baseShowNewSmsHeadImage);
		edit.commit();
		this.baseShowNewSmsHeadImage = baseShowNewSmsHeadImage;
	}
	
	Boolean baseShowSendBackMsg;
	public boolean getBaseShowSendBackMsg(){
		if(baseShowSendBackMsg == null)
			baseShowSendBackMsg = application.getDefaultSharedPreferences().getBoolean("baseShowSendBackMsg", false);
		return baseShowSendBackMsg;
	}

	public void setBaseShowSendBackMsg(boolean baseShowSendBackMsg){
		edit.putBoolean("baseShowSendBackMsg", baseShowSendBackMsg);
		edit.commit();
		this.baseShowSendBackMsg = baseShowSendBackMsg;
	}
	
	String baseSafetyCipher;
	public String getBaseSafetyCipher(){
		if(baseSafetyCipher == null)
			baseSafetyCipher = application.getDefaultSharedPreferences().getString("baseSafetyCipher", "");
		return baseSafetyCipher;
	}

	public void setBaseSafetyCipher(String baseSafetyCipher){
		edit.putString("baseSafetyCipher", baseSafetyCipher);
		edit.commit();
		this.baseSafetyCipher = baseSafetyCipher;
	}
	
	Boolean baseCipherViewVibor;
	public boolean getBaseCipherViewVibor(){
		if(baseCipherViewVibor == null)
			baseCipherViewVibor = application.getDefaultSharedPreferences().getBoolean("baseCipherViewVibor", false);
		return baseCipherViewVibor;
	}

	public void setBaseCipherViewVibor(boolean baseCipherViewVibor){
		edit.putBoolean("baseCipherViewVibor", baseCipherViewVibor);
		edit.commit();
		this.baseCipherViewVibor = baseCipherViewVibor;
	}
	
	Boolean baseCipherViewVisible;
	public boolean getBaseCipherViewVisible(){
		if(baseCipherViewVisible == null)
			baseCipherViewVisible = application.getDefaultSharedPreferences().getBoolean("baseCipherViewVisible", true);
		return baseCipherViewVisible;
	}

	public void setBaseCipherViewVisible(boolean baseCipherViewVisible){
		edit.putBoolean("baseCipherViewVisible", baseCipherViewVisible);
		edit.commit();
		this.baseCipherViewVisible = baseCipherViewVisible;
	}
	
	Boolean baseSendInfoMsg;
	public boolean getBaseSendInfoMsg(){
		if(baseSendInfoMsg == null)
			baseSendInfoMsg = application.getDefaultSharedPreferences().getBoolean("baseSendInfoMsg", false);
		return baseSendInfoMsg;
	}

	public void setBaseSendInfoMsg(boolean baseSendInfoMsg){
		edit.putBoolean("baseSendInfoMsg", baseSendInfoMsg);
		edit.commit();
		this.baseSendInfoMsg = baseSendInfoMsg;
	}
	
	String baseSignature;
	public String getBaseSignature(){
		if(baseSignature == null)
			baseSignature = application.getDefaultSharedPreferences().getString("baseSignature", "无");
		return baseSignature;
	}

	public void setBaseSignature(String baseSignature){
		edit.putString("baseSignature", baseSignature);
		edit.commit();
		this.baseSignature = baseSignature;
	}
}
